package cn.signalpha.modules.shop.listener;

import cn.signalpha.common.utils.Arith;
import cn.signalpha.core.redis.cache.RedisCache;
import cn.signalpha.core.tool.jackson.JsonUtil;
import cn.signalpha.core.tool.utils.ObjectUtil;
import cn.signalpha.modules.base.dto.NoticeDTO;
import cn.signalpha.modules.base.entity.enums.NoticeTypeEnum;
import cn.signalpha.modules.com.dto.UserLevelLogDTO;
import cn.signalpha.modules.com.dto.WalletDTO;
import cn.signalpha.modules.com.entity.User;
import cn.signalpha.modules.com.entity.UserLevel;
import cn.signalpha.modules.com.entity.enums.LevelSourceEnum;
import cn.signalpha.modules.com.entity.enums.WalletSourceEnum;
import cn.signalpha.modules.com.entity.enums.WalletTypeEnum;
import cn.signalpha.modules.com.service.UserLevelService;
import cn.signalpha.modules.com.service.UserService;
import cn.signalpha.modules.queue.enums.RedisDelayQueueEnum;
import cn.signalpha.modules.queue.utils.RedisDelayQueueUtil;
import cn.signalpha.modules.resource.builder.sms.SmsBuilder;
import cn.signalpha.modules.shop.dto.OrderDTO;
import cn.signalpha.modules.shop.entity.*;
import cn.signalpha.modules.shop.event.OrderPaySuccessEvent;
import cn.signalpha.modules.shop.order.OrderPaySuccessOrder;
import cn.signalpha.modules.shop.service.*;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单支付成功
 */
@AllArgsConstructor
@Component("orderPaySuccessListener")
public class OrderPaySuccessListener {

	private final SmsBuilder smsBuilder;
	private final RedisCache redisCache;
	private final UserService userService;
	private final GoodsService goodsService;
	private final OrderService orderService;
	private final SellerService sellerService;
	private final UserLevelService userLevelService;
	private final PublicityService publicityService;
	private final PlaceLevelService placeLevelService;
	private final OrderSettleService orderSettleService;
	private final OrderDetailService orderDetailService;
	private final RedisDelayQueueUtil redisDelayQueueUtil;
	private final PatternGoodsService patternGoodsService;
	private final ApplicationEventPublisher eventPublisher;
	private final PublicityGoodsService publicityGoodsService;
	private final OrderSettlePlaceService orderSettlePlaceService;

	/**
	 * 默认场景
	 */
    @EventListener(OrderPaySuccessEvent.class)
	@org.springframework.core.annotation.Order(OrderPaySuccessOrder.DEFAULT)
    public void defaultOrderPaySuccessListener(OrderPaySuccessEvent event) {
        List<Order> orderList = event.getOrderList();
        for(Order order : orderList){

			//取订单详情
			List<OrderDetail> orderDetailList = orderDetailService.getByOrderNo(order.getOrderNo());
			order.setOrderDetailList(orderDetailList);

			//增加销量
			Map<Long, Integer> goodsCollect = new HashMap<>(16);
			orderDetailList.stream().collect(Collectors.groupingBy(OrderDetail::getGoodsId)).forEach((goodsId, item) -> {
				goodsCollect.put(goodsId, item.stream().mapToInt(i -> JsonUtil.parse(i.getGoodsDetail(), OrderDTO.DetailDTO.class).getGoodsNum()).sum());
			});
			goodsService.addSalesVolume(goodsCollect);
		}
    }

	/**
	 * 营销活动场景
	 */
	@EventListener(OrderPaySuccessEvent.class)
	@org.springframework.core.annotation.Order(OrderPaySuccessOrder.PUBLICITY)
	public void publicityOrderPaySuccessListener(OrderPaySuccessEvent event) {
		List<Order> orderList = event.getOrderList();
		for(Order order : orderList){
			for(OrderDetail orderDetail : order.getOrderDetailList()){
				if(ObjectUtil.isNotEmpty(orderDetail.getDeductPublicityId()) && orderDetail.getDeductPublicityId() > 0){
					PublicityGoods publicityGoods = publicityGoodsService.getOne(Wrappers.<PublicityGoods>lambdaQuery()
						.eq(PublicityGoods::getGoodsId, orderDetail.getGoodsId())
						.eq(PublicityGoods::getPublicityId, orderDetail.getDeductPublicityId())
						.last("limit 1")
					);
					if(ObjectUtil.isNotEmpty(publicityGoods)){
						publicityGoodsService.updateById(PublicityGoods.builder().id(publicityGoods.getId()).salesVolume(publicityGoods.getSalesVolume() + orderDetail.getGoodsNum()).build());
					}
				}
			}
		}
	}

	/**
	 * 余额抵扣场景
	 */
	@EventListener(OrderPaySuccessEvent.class)
	@org.springframework.core.annotation.Order(OrderPaySuccessOrder.MONEY_DEDUCT)
	public void moneyDeductOrderPaySuccessListener(OrderPaySuccessEvent event) {
		List<Order> orderList = event.getOrderList();
		for(Order order : orderList){
			//扣除金额
			if(order.getDeductMoney() > 0){
				userService.updateUserMoney(WalletDTO.builder()
					.userId(order.getUserId())
					.amount(order.getDeductMoney())
					.type(WalletTypeEnum.SUB.getType())
					.sourceId(order.getOrderNo())
					.sourceType(WalletSourceEnum.GOODS.getType())
					.remark(order.getGoodsName())
					.build());
			}
		}
	}

	/**
	 * 积分抵扣场景
	 */
	@EventListener(OrderPaySuccessEvent.class)
	@org.springframework.core.annotation.Order(OrderPaySuccessOrder.INTEGRAL_DEDUCT)
	public void integralDeductOrderPaySuccessListener(OrderPaySuccessEvent event) {
		List<Order> orderList = event.getOrderList();
		for(Order order : orderList){
			//扣除积分
			if(order.getDeductIntegral() > 0){
				userService.updateUserIntegral(WalletDTO.builder()
					.userId(order.getUserId())
					.amount(order.getDeductIntegral())
					.type(WalletTypeEnum.SUB.getType())
					.sourceId(order.getOrderNo())
					.sourceType(WalletSourceEnum.GOODS.getType())
					.remark("购买" + order.getGoodsName())
					.build());
			}
		}
	}

	/**
	 * 奖励经验场景
	 */
	@EventListener(OrderPaySuccessEvent.class)
	@org.springframework.core.annotation.Order(100)
	public void levelOrderPaySuccessListener(OrderPaySuccessEvent event) {
		List<Order> orderList = event.getOrderList();
		for(Order order : orderList){
			//奖励经验
			int amount = (int) Math.ceil(order.getOrderPrice());
			if(amount > 0){
				User user = userService.getById(order.getUserId());
				UserLevel userLevel = userLevelService.getById(user.getLevel());
				if(ObjectUtil.isNotEmpty(userLevel)){
					int totalAmount = amount * userLevel.getExpOrder();
					userService.updateUserExp(UserLevelLogDTO.builder()
						.userId(order.getUserId())
						.amount(totalAmount)
						.sourceId(order.getOrderNo())
						.sourceType(LevelSourceEnum.ORDER.getType())
						.remark(LevelSourceEnum.ORDER.getName())
						.build());
				}
			}
		}
	}

	/**
	 * 积分奖励场景
	 */
//	@EventListener(OrderPaySuccessEvent.class)
//	@org.springframework.core.annotation.Order(101)
//	public void integralAwardOrderPaySuccessListener(OrderPaySuccessEvent event) {
//		List<Order> orderList = event.getOrderList();
//		for(Order order : orderList){
//			//奖励积分
//			int amount = (int) Math.ceil(Arith.add(order.getOrderPrice(), order.getDeductMoney()));
//			if(amount > 0){
//				ConfigDTO.ShopDTO config = ConfigCache.getObject(ConfigKeys.SHOP, ConfigDTO.ShopDTO.class);
//				int times = (int) Arith.div(amount, config.getIntegralPayMoney());
//				double totalAmount = Arith.mul(times, config.getIntegralAward());
//				if(totalAmount > 0){
//					userService.updateUserIntegral(WalletDTO.builder()
//						.userId(order.getUserId())
//						.amount(order.getDeductIntegral())
//						.type(WalletTypeEnum.ADD.getType())
//						.sourceId(order.getOrderNo())
//						.sourceType(WalletSourceEnum.GOODS.getType())
//						.remark("购买" + order.getGoodsName())
//						.build());
//				}
//			}
//		}
//	}

	/**
	 * 佣金场景
	 */
	@EventListener(OrderPaySuccessEvent.class)
	@org.springframework.core.annotation.Order(501)
	public void indirectOrderPaySuccessListener(OrderPaySuccessEvent event) {
		List<Order> orderList = event.getOrderList();
		for(Order order : orderList){
			User user = userService.getById(order.getUserId());
			double directMoney = 0, indirectMoney = 0;
			for(OrderDetail orderDetail : order.getOrderDetailList()){
				directMoney = Arith.add(directMoney, orderDetail.getDirectMoney());
				indirectMoney = Arith.add(indirectMoney, orderDetail.getIndirectMoney());
			}

			if(directMoney >= 0){
				OrderSettle orderSettle = orderSettleService.getByOrderNo(order.getOrderNo());
				orderSettleService.updateById(OrderSettle.builder()
					.id(orderSettle.getId())
					.settleAmount(Arith.sub(orderSettle.getSettleAmount(), directMoney))
					.build()
				);

				OrderSettlePlace orderSettlePlace = new OrderSettlePlace();
				orderSettlePlace.setUserId(user.getParentId());
				orderSettlePlace.setSellerId(order.getSellerId());
				orderSettlePlace.setOrderNo(order.getOrderNo());
				orderSettlePlace.setOrderUserId(order.getUserId());
				orderSettlePlace.setPayNo(orderSettle.getPayNo());
				orderSettlePlace.setPayBizNo(orderSettle.getPayBizNo());
				orderSettlePlace.setPayType(orderSettle.getPayType());
				orderSettlePlace.setPayAmount(order.getOrderPrice());
				orderSettlePlace.setSettleType(WalletSourceEnum.DIRECT.getType());
				orderSettlePlace.setSettleWay(2);
				orderSettlePlace.setSettleAmount(directMoney);
				orderSettlePlace.setSettleStatus(0);
				orderSettlePlace.setCreateTime(order.getPayTime());
				orderSettlePlaceService.save(orderSettlePlace);

				//推送消息
				NoticeDTO noticeDTO = new NoticeDTO();
				noticeDTO.setTargetId(orderSettlePlace.getId());
				noticeDTO.setType(NoticeTypeEnum.BROKERAGE.getType());
				redisDelayQueueUtil.addDelayQueue(noticeDTO, 3, RedisDelayQueueEnum.NOTICE.getCode());
			}

			if(indirectMoney >= 0){
				OrderSettle orderSettle = orderSettleService.getByOrderNo(order.getOrderNo());
				orderSettleService.updateById(OrderSettle.builder()
					.id(orderSettle.getId())
					.settleAmount(Arith.sub(orderSettle.getSettleAmount(), indirectMoney))
					.build()
				);

				OrderSettlePlace orderSettlePlace = new OrderSettlePlace();
				orderSettlePlace.setUserId(user.getGrandpaId());
				orderSettlePlace.setSellerId(order.getSellerId());
				orderSettlePlace.setOrderNo(order.getOrderNo());
				orderSettlePlace.setOrderUserId(order.getUserId());
				orderSettlePlace.setPayNo(orderSettle.getPayNo());
				orderSettlePlace.setPayBizNo(orderSettle.getPayBizNo());
				orderSettlePlace.setPayType(orderSettle.getPayType());
				orderSettlePlace.setPayAmount(order.getOrderPrice());
				orderSettlePlace.setSettleType(WalletSourceEnum.INDIRECT.getType());
				orderSettlePlace.setSettleWay(2);
				orderSettlePlace.setSettleAmount(indirectMoney);
				orderSettlePlace.setSettleStatus(0);
				orderSettlePlace.setCreateTime(order.getPayTime());
				orderSettlePlaceService.save(orderSettlePlace);

				//推送消息
				NoticeDTO noticeDTO = new NoticeDTO();
				noticeDTO.setTargetId(orderSettlePlace.getId());
				noticeDTO.setType(NoticeTypeEnum.BROKERAGE.getType());
				redisDelayQueueUtil.addDelayQueue(noticeDTO, 3, RedisDelayQueueEnum.NOTICE.getCode());
			}
		}
	}

}
